#!/usr/bin/env python
# -*- coding: utf-8 -*-
import json
import os
from sys import argv
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from pdfminer.pdfpage import PDFPage, PDFTextExtractionNotAllowed
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams
from io import StringIO

from Conditions import Conditions


class SolutionMatcher:
	def __init__(self):
		pass

	@staticmethod
	def readPdf(path):
		contents = []
		with open(path, 'rb') as f:
			parser = PDFParser(f)

			doc = PDFDocument(parser)

			if not doc.is_extractable:
				raise PDFTextExtractionNotAllowed

			pdfrm = PDFResourceManager()

			laparams = LAParams()

			device = PDFPageAggregator(pdfrm, laparams=laparams)

			interpreter = PDFPageInterpreter(pdfrm, device)

			for pageIdx, page in enumerate(PDFPage.create_pages(doc)):
				output = StringIO()
				interpreter.process_page(page)
				layout = device.get_result()
				for x in layout:
					if hasattr(x, "get_text"):
						content = x.get_text()
						output.write(content)
				contents.append(output.getvalue())
				output.close()
		return contents

	@staticmethod
	def splitContent(text, separations):
		separatedContent = []
		remainContent = text
		for separation in separations:
			sepPos = remainContent.find(separation)
			if sepPos != -1:
				separatedContent.append(remainContent[0:sepPos])
				remainContent = remainContent[sepPos:]
			else:
				continue
		separatedContent.append(remainContent)
		return separatedContent

	@staticmethod
	def getIndexDict(text, pageNo):
		indexDicts = []
		availableIndexes = []
		currentIndex = text.find('\n')
		while currentIndex != -1 and currentIndex+5 < len(text):
			conditions = Conditions()
			conditions.addCondition('is digit', (text[currentIndex+1].isdigit() and '.' in text[currentIndex:currentIndex+5]))
			conditions.addCondition('is (N)', (text[currentIndex+1] == '(' and ')' in text[currentIndex:currentIndex+5] and text[currentIndex+2].isdigit()))
			conditions.addCondition('is chn (N)', (text[currentIndex+1] == '（' and '）' in text[currentIndex:currentIndex+5] and text[currentIndex+2].isdigit()))
			# print("{} / {} / {}".format(currentIndex+1, text[currentIndex+1], text[currentIndex+1:currentIndex+5]))
			if not conditions.isAllFalse():
				availableIndexes.append(currentIndex+1)
			currentIndex = text.find('\n', currentIndex+2)
		for (i, index) in enumerate(availableIndexes):
			dotPos = text[index:index+5].find('.')
			parPos = text[index:index+5].find('(')
			chn_parPos = text[index:index+5].find('（')
			if i + 1 < len(availableIndexes):
				nextIndex = availableIndexes[i + 1]
				if dotPos != -1:
					indexDicts.append({
						'pos': index,
						'page': pageNo,
						'tag': text[index:index+5][dotPos-1:dotPos+3],
						'text': text[index:nextIndex]
					})
				elif parPos != -1:
					indexDicts.append({
						'pos': index,
						'page': pageNo,
						'tag': text[index:index+5][parPos:parPos + 3],
						'text': text[index:nextIndex]
					})
				elif chn_parPos != -1:
					indexDicts.append({
						'pos': index,
						'page': pageNo,
						'tag': text[index:index + 5][chn_parPos:chn_parPos + 3],
						'text': text[index:nextIndex]
					})
		return indexDicts

	@staticmethod
	def matchPosition(text, indexDictionary: list):
		matchedPosition = {}
		for dictionary in indexDictionary:
			if text in dictionary['text']:
				matchedPosition = {
					'page': dictionary['page'],
					'tag': dictionary['tag']
				}
		return matchedPosition

	@staticmethod
	def getKeyWords(questionDicts: list):
		keywords = []
		for question in questionDicts:
			keywords.append({
				'tag': question['tag'],
				'keyword': question['text'][4:12]
			})
		return keywords


if __name__ == '__main__':
	script, originBase, outputBase, pdf = argv
	if not os.path.exists('AnswerBase.json'):
		# PDF转Json
		textList = SolutionMatcher.readPdf(pdf)
		indexDicts = []
		for pageNo, text in enumerate(textList):
			text = text.replace('     ', '').replace('(A)', '').replace('(B)', '').replace('(C)', '').replace('(D)', '')
			indexDicts.extend(SolutionMatcher.getIndexDict(text, pageNo + 1))
		with open('AnswerBase.json', 'w', encoding='utf-8') as f:
			jsonText = json.dumps(indexDicts, indent=2, ensure_ascii=False)
			jsonText = jsonText.replace('\\n', '').replace(' ', '')
			f.write(jsonText)
		f.close()
		print("提取完成，共{}个答案".format(len(indexDicts)))

	# 读取答案库
	with open('AnswerBase.json', 'r', encoding='utf-8') as f:
		jsonText = f.read()
	f.close()
	answerBase = json.loads(jsonText)
	# 读取题目
	with open(originBase, 'r', encoding='utf-8') as f:
		text = f.read()
	f.close()
	# 题目预处理
	text = text.replace('　', '').replace(' ', '').replace('(A)', '').replace('(B)', '').replace('(C)', '').replace('(D)', '').replace('\n\n', '')
	# 获取题目对象
	questions = SolutionMatcher.getIndexDict(text, 0)
	# 提取题目关键字
	keywords = SolutionMatcher.getKeyWords(questions)
	# 匹配答案
	matchedQuestions = []
	for keyword in keywords:
		matched = SolutionMatcher.matchPosition(keyword['keyword'], answerBase)
		if matched == {}:
			continue
		matchedQuestions.append({
			'tag': keyword['tag'],
			'ansPage': matched['page'],
			'ansTag': matched['tag'],
			'fragment': keyword['keyword']
		})
	# 答案输出
	with open(outputBase, 'w', encoding='utf-8') as f:
		jsonText = json.dumps(matchedQuestions, indent=2, ensure_ascii=False)
		f.write(jsonText)
	f.close()
